package com.fuego.creditsystemcommodity.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuego.creditsystemcommodity.mapper.ActivityOrderMapper;
import com.fuego.creditsystemcommodity.service.IActivityInfoService;
import com.fuego.creditsystemcommodity.service.IActivityOrderService;
import com.fuego.creditsystemcommodity.service.IActivityService;
import jakarta.annotation.Resource;
import org.example.dto.Result;
import org.example.entity.ActivityOrder;
import org.example.utils.RedisIdWorker;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

import static org.example.utils.RedisConstants.ACTIVITY_INFO_STOCK_KEY;

@Service
public class ActivityOrderServiceImpl extends ServiceImpl<ActivityOrderMapper, ActivityOrder> implements IActivityOrderService {

    @Resource
    private IActivityInfoService activityInfoService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedisIdWorker redisIdWorker;
    @Resource
    private IActivityService activityService;



    @Override
    @Transactional
    public Result activityInfo(Long activityId, Long userId, LocalDateTime activityStartTime) {

        Boolean alreadyJoin=this.query()
                .eq("user_id",userId)
                .eq("activity_id",activityId)
                .eq("activity_start_time",activityStartTime)
                .list().size()>0;
        if(alreadyJoin){
            return Result.fail("用户已报名当前活动，无法重复报名");
        }

        // 验证输入参数
        if (activityId == null || userId == null || activityStartTime == null) {
            return Result.fail("参数不完整或无效");
        }

            String stockKey = ACTIVITY_INFO_STOCK_KEY + activityId + ":" + activityStartTime;
            String stockStr = stringRedisTemplate.opsForValue().get(stockKey);
            if (stockStr == null) {
                return Result.fail("库存键不存在: " + stockKey);
            }
            long stock = Long.parseLong(stockStr);
            if (stock <= 0) {
                return Result.fail("活动报名人数已满" );
            }

        // 扣减 Redis 库存
        try {

            Long newStock = stringRedisTemplate.opsForValue().increment(stockKey, -1);
            if (newStock == null || newStock < 0) {
                throw new RuntimeException("Redis 库存扣减失败: " + stockKey);
            }

        } catch (Exception e) {
            log.error("Redis 库存扣减失败", e);
            // 回滚已扣减的 Redis 库存

            stringRedisTemplate.opsForValue().increment(stockKey, 1);

            return Result.fail("Redis 库存扣减失败: " + e.getMessage());
        }

        // 创建订单并扣减数据库库存

        try {

                long orderId = redisIdWorker.nextId("activityorder");
                if (orderId == 0) {
                    throw new RuntimeException("生成订单ID失败");
                }

                ActivityOrder activityOrder = new ActivityOrder();
                activityOrder.setActivityId(activityId);
                activityOrder.setUserId(userId);
                activityOrder.setId(orderId);
                activityOrder.setStatus(1); // 订单状态：未支付
                activityOrder.setCreateTime(LocalDateTime.now());
                activityOrder.setActivityStartTime(activityStartTime); // 设置入住日期
                activityOrder.setActivityEndTime(activityService.getById(activityId).getActivityEndTime()); // 设置入住日期

            createActivityOrder(activityOrder, activityStartTime);
            return Result.ok(orderId);
        } catch (Exception e) {
            log.error("订单创建或数据库库存扣减失败", e);
            // 回滚 Redis 库存
            stringRedisTemplate.opsForValue().increment(stockKey, 1);
            // 事务会自动回滚数据库操作
            return Result.fail("订单创建失败: " + e.getMessage());
        }
    }

    @Transactional
    public void createActivityOrder(ActivityOrder activityOrder, LocalDateTime activityStartTime) {
        // 扣减数据库库存
        boolean success = activityInfoService.update()
                .setSql("stock = stock - 1")
                .eq("activity_id", activityOrder.getActivityId())
                .eq("activity_start_time", activityStartTime)
                .gt("stock", 0)
                .update();
        if (!success) {
            log.error("数据库库存不足: activity_id=" + activityOrder.getActivityId() + ", activity_start_time=" + activityStartTime);
            throw new RuntimeException("数据库库存不足: " + activityStartTime);
        }

        // 保存订单
        save(activityOrder);
    }
    @Resource
    private ActivityOrderMapper activityOrderMapper;

    @Override
    public Result queryAllOrders(Long userId) {
        if (userId == null) {
            return Result.fail("用户ID不能为空");
        }

        List<ActivityOrder> activityOrders = getBaseMapper().queryAllOrders(userId);
        return Result.ok(activityOrders);
    }

    @Transactional
    @Override
    public Result refund(Long orderId) {
        if (orderId == null) {
            return Result.fail("订单ID不能为空");
        }
        ActivityOrder order = this.query()
                .eq("id", orderId)
                .list()
                .stream()
                .findFirst()
                .orElse(null);

        if (order == null) {
            return Result.fail("订单不存在");
        }
        if (order.getStatus() == 2) {
            return Result.fail("订单已退款");
        }

        // 恢复数据库库存
        boolean success;


            // 恢复 Redis 库存
            LocalDateTime refundTime = order.getActivityStartTime();
            String stockKey = "activityinfo:stock:" +refundTime+ order.getActivityId() + ":" +refundTime;
            stringRedisTemplate.opsForValue().increment(stockKey, 1);

            // 恢复数据库库存
            success = activityInfoService.update()
                    .setSql("stock = stock + 1")
                    .eq("activity_id", order.getActivityId())
                    .eq("activity_start_time", order.getActivityStartTime())
                    .update();
            if (!success) {
                log.error("数据库库存恢复失败: activity_id=" + order.getActivityId() + ", activity_start_time=" + order.getActivityStartTime());
                throw new RuntimeException("数据库库存恢复失败: " + order.getActivityStartTime());
            }


        // 更新订单状态
        success = this.update()
                .eq("id", orderId)
                .set("status", 2) // 设置为已退款
                .set("cancel_time", LocalDateTime.now())
                .update();
        if (!success) {
            return Result.fail("退款失败");
        }

        return Result.ok("退款成功");
    }
}
